package com.slipper.system.scheduled;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

import com.slipper.common.exception.CommonException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.ReflectionUtils;

import com.slipper.PaasContext;
import com.slipper.system.api.schedule.bo.ScheduleBO;

/**
 * 执行定时任务
 */
public class ScheduledRunnable implements Runnable {
    private final Logger logger = LoggerFactory.getLogger(getClass());
    
    private final ScheduleBO scheduleBO;
    private final String beanName;
    private final String methodName;
    private final String params;

    public ScheduledRunnable(ScheduleBO scheduleBO, String beanName, String methodName, String params) {
        this.scheduleBO = scheduleBO;
        this.beanName = beanName;
        this.methodName = methodName;
        this.params = params;
    }

    @Override
    public void run() {
        try {
            Object target = PaasContext.getBean(this.beanName);
            Method method = null;
            List<Object> paramList = new ArrayList<>();
            Method[] methods = target.getClass().getDeclaredMethods();
            for (Method item : methods) {
                if (item.getName().equals(this.methodName)) {
                    method = item;
                    break;
                }
            }
            if (method == null) {
                throw new CommonException("Bean: " + beanName + "，无此方法：" + this.methodName);
            }
            
            for (Class<?> clazz : method.getParameterTypes()) {
                if (clazz == ScheduleBO.class) {
                    paramList.add(this.scheduleBO);
                } else if (clazz == String.class) {
                    paramList.add(this.params);
                }
            }
            
            ReflectionUtils.makeAccessible(method);
            if (!paramList.isEmpty()) {
                method.invoke(target, paramList.toArray());
            } else {
                method.invoke(target);
            }
        } catch (Exception e) {
            logger.error("执行定时任务失败！", e);
            throw new CommonException("执行定时任务失败, " + e.getMessage(), e);
        }
    }
}
